package base.bitmap {
	import base.Singleton;
	import flash.display.DisplayObject;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.geom.Matrix;
	import flash.geom.ColorTransform;
	import flash.display.BlendMode;
	import flash.display.Shape;
	import flash.display.GradientType;
	import base.bitmap.BitmapExt;
	import flash.geom.Rectangle;
	import flash.display.Stage;
	import flash.display.StageQuality;
	import flash.geom.Point;	

	public class BitmapUtils extends Singleton {

		private static const toRadians: Number = Math.PI / 180;
		
		public static function drawReflection(dspObjToDrawReflection: DisplayObject, bmpReflection: Bitmap = null): Bitmap {
			var bmpDataReflection: BitmapData = new BitmapData(dspObjToDrawReflection.width, dspObjToDrawReflection.height);
			bmpDataReflection.fillRect(bmpDataReflection.rect, 0x00FFFFFF);
			var mrxReflection: Matrix = new Matrix();
			mrxReflection.scale(1, -1);
			mrxReflection.translate(0, dspObjToDrawReflection.height);
			bmpDataReflection.draw(dspObjToDrawReflection, mrxReflection, new ColorTransform(1, 1, 1, 0.7), BlendMode.SCREEN, null, true);
			var holder: Shape = new Shape();
			var mrxReflectionGradient: Matrix = new Matrix();
			mrxReflectionGradient.createGradientBox(dspObjToDrawReflection.width, dspObjToDrawReflection.height, 270 * BitmapUtils.toRadians);
			holder.graphics.beginGradientFill( GradientType.LINEAR, [ 0, 0 ], [0, 100], [0x33, 0xFF], mrxReflectionGradient)
			holder.graphics.drawRect(0, 0, dspObjToDrawReflection.width, dspObjToDrawReflection.height);
			holder.graphics.endFill();
			mrxReflection = new Matrix();
			bmpDataReflection.draw(holder, mrxReflection, null, BlendMode.ALPHA);
			if (bmpReflection == null) {
				bmpReflection = new BitmapExt(bmpDataReflection, "auto", true);
			} else {
				bmpReflection.bitmapData.dispose();
				bmpReflection.bitmapData = bmpDataReflection;
			}
			bmpReflection.x = dspObjToDrawReflection.x;
			bmpReflection.y = dspObjToDrawReflection.y + dspObjToDrawReflection.height;
			return bmpReflection;
		}
		
		public static function drawMiniature(bmpDataSrc: BitmapData, dimensionMiniature: Rectangle, isCropEmptySpace: uint = 0, stage: Stage = null): BitmapData {
			var ratioWidthToHeightDimensionMiniature: Number = dimensionMiniature.width / dimensionMiniature.height;
			var ratioWidthToHeightBmpDataSrc: Number = bmpDataSrc.width / bmpDataSrc.height;
			var scale: Number;
			var translateX: Number;
			var translateY: Number;
			if (uint(ratioWidthToHeightDimensionMiniature > ratioWidthToHeightBmpDataSrc) == isCropEmptySpace) {
				scale = dimensionMiniature.height / bmpDataSrc.height;
				translateX = -(bmpDataSrc.width * scale - dimensionMiniature.width) / 2;
				translateY = 0;
			} else {
				scale = dimensionMiniature.width / bmpDataSrc.width;
				translateX = 0;
				translateY = -(bmpDataSrc.height * scale - dimensionMiniature.height) / 2;
			}
			var mrxScaleTranslateBmpDataMiniature: Matrix = new Matrix();
			mrxScaleTranslateBmpDataMiniature.scale(scale, scale);
			mrxScaleTranslateBmpDataMiniature.translate(translateX, translateY);
			var bmpDataMiniature: BitmapData = new BitmapData(dimensionMiniature.width, dimensionMiniature.height, true, 0xFFFFFF);
			if (stage) stage.quality = StageQuality.BEST;
			bmpDataMiniature.draw(bmpDataSrc, mrxScaleTranslateBmpDataMiniature, null, null, null, true);
			if (stage) stage.quality = StageQuality.HIGH;
			return bmpDataMiniature;			
		}
		
		public static function drawCrop(bmpDataSrc: BitmapData, dimensionCrop: Rectangle): BitmapData {
			var bmpDataCrop: BitmapData = new BitmapData(dimensionCrop.width, dimensionCrop.height, true, 0xFFFFFF);
			bmpDataCrop.copyPixels(bmpDataSrc, new Rectangle((bmpDataSrc.width - dimensionCrop.width) / 2, (bmpDataSrc.height - dimensionCrop.height) / 2, dimensionCrop.width, dimensionCrop.height), new Point(0, 0));
			return bmpDataCrop;
		}
		
		public static function grab(source:DisplayObject, rect:Rectangle, smoothing:Boolean=true):BitmapData {
            var draw:BitmapData = new BitmapData( source.width, source.height, true, 0 );
            var copy:BitmapData = new BitmapData( rect.width, rect.height, true, 0 );
            draw.draw( source, null, null, null, null, smoothing );
            copy.copyPixels( draw, rect, new Point( 0, 0 ) );
            draw.dispose();
            return copy;
        }
		
	}
	
}